﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

// NotReviewedButNeeded
#pragma once

#include "GcmpDevService.h"
#include <unordered_map>
#include "OwnerPtr.h"

namespace gcmp
{
    class CommandParameterValueImpl;

    /// \brief 命令参数的Value类型定义
    ///
    /// \当前只支持常见基础类型作为命令参数的值类型
    class GCMP_DEV_SERVICE_EXPORT CommandParameterValue
    {
    public:
        CommandParameterValue();
        /// \brief 构造一个Int32的参数值
        /// \param [in] value 参数值
        CommandParameterValue(int32_t value);
        /// \brief 构造一个UInt32的参数值
        /// \param [in] value 参数值
        CommandParameterValue(uint32_t value);
        /// \brief 构造一个Int64的参数值
        /// \param [in] value 参数值
        CommandParameterValue(int64_t value);
        /// \brief 构造一个UInt64的参数值
        /// \param [in] value 参数值
        CommandParameterValue(uint64_t value);
        /// \brief 构造一个double的参数值
        /// \param [in] value 参数值
        CommandParameterValue(double value);
        /// \brief 构造一个float的参数值
        /// \param [in] value 参数值
        CommandParameterValue(float value);
        /// \brief 构造一个bool的参数值
        /// \param [in] value 参数值
        CommandParameterValue(bool value);
        /// \brief 构造一个wstring的参数值
        /// \param [in] value 参数值
        CommandParameterValue(const std::wstring& value);
        /// \brief 构造一个wchar_t*的参数值
        /// \param [in] pValue 参数值，传入空指针会报错，且生成的实例存储的是个空字符串
        CommandParameterValue(const wchar_t *pValue);
        /// \brief 拷贝构造函数
        /// \param [in] value 另一个命令参数
        CommandParameterValue(const CommandParameterValue& value);
        /// \brief 右值构造函数
        /// \param [in] value 参数值
        CommandParameterValue(CommandParameterValue&& value);
        
        /// \brief 赋值重载函数
        CommandParameterValue& operator=(const CommandParameterValue & other);

        /// \brief 重载 <运算符
        bool operator<(const CommandParameterValue& other) const;
        /// \brief 重载 <= 运算符
        bool operator<=(const CommandParameterValue& other) const;
        /// \brief 重载 >= 运算符
        bool operator>=(const CommandParameterValue& other) const;
        /// \brief 重载 > 运算符
        bool operator>(const CommandParameterValue& other) const;
        /// \brief 重载 == 运算符
        bool operator==(const CommandParameterValue& other) const;
        /// \brief 重载 != 运算符
        bool operator!=(const CommandParameterValue& other) const;

        /// \brief 当保存的值类型为Int时的取值接口
        /// \return Int32 实际保存的值
        int32_t AsInt() const;
        /// \brief 当保存的值类型为UInt时的取值接口
        /// \return UInt32 实际保存的值
        uint32_t AsUInt() const;
        /// \brief 当保存的值类型为Int64时的取值接口
        /// \return Int64 实际保存的值
        int64_t AsInt64() const;
        /// \brief 当保存的值类型为UInt64时的取值接口
        /// \return Int64 实际保存的值
        uint64_t AsUInt64() const;
        /// \brief 当保存的值类型为Float时的取值接口
        /// \return Float 实际保存的值
        float AsFloat() const;
        /// \brief 当保存的值类型为Double时的取值接口
        /// \return Double 实际保存的值
        double AsDouble() const;
        /// \brief 当保存的值类型为Bool时的取值接口
        /// \return Bool 实际保存的值
        bool AsBool() const;
        /// \brief 当保存的值类型为Wstring时的取值接口
        /// \return wstring 实际保存的值
        std::wstring AsWString() const;

        /// \brief 判断是否为空
        bool IsNull() const;
        /// \brief 判断是否为Bool类型
        bool IsBool() const;
        /// \brief 判断是否为Int类型
        bool IsInt() const;
        /// \brief 判断是否为Int64类型
        bool IsInt64() const;
        /// \brief 判断是否为UInt类型
        bool IsUInt() const;
        /// \brief 判断是否为UInt64类型
        bool IsUInt64() const;
        /// \brief 判断是否为Double类型
        bool IsDouble() const;
        /// \brief 判断是否为wstring类型
        bool IsWString() const;

        /// \brief 将命令参数值序列化成wstring 类型字符串
        /// \param [in] 需要系列化的参数值
        /// \return std::wstring 序列化成功后的字符串，序列化失败则字符串长度为0
        static std::wstring Serialize(const CommandParameterValue& val);

        /// \brief 从字符串中反序列出命令参数值
        /// \param [in] 需要反序列化的字符串
        /// \return CommandParameterValue 反序列化成功后的参数值，序列化失败则对象为空
        static CommandParameterValue Unserialize(const std::wstring& str);

        
        ~CommandParameterValue();
    protected:
        void SetImpl(OwnerPtr<CommandParameterValueImpl>& impl);
        const OwnerPtr<CommandParameterValueImpl>& GetImpl() const ;
        OwnerPtr<CommandParameterValueImpl>& GetImpl();
    private:
        OwnerPtr<CommandParameterValueImpl> m_impl;
    };

    /// \brief 命令参数的Key类型定义
    using CommandParameterKey = std::wstring;

    /// \brief 命令参数类型定义
    /// 
    /// \notes 由于命令参数操作大部分都是插入和查找操作， 所以当前使用std::unordered_map
    class CommandParameters : public std::unordered_map<CommandParameterKey, CommandParameterValue> {};

}
